﻿using System;

public class CMyArray<_Ty>
{
    _Ty[] m_pData;
    int m_nLeng;
    public CMyArray()
    {
        m_pData = new _Ty[0];
        m_nLeng = 0;
    }
    public bool reserve(int nSize)
    {
        if (nSize <= m_pData.Length)
            return true;
        _Ty[] pData = new _Ty[nSize];
        if (m_nLeng > 0)
            Array.Copy(m_pData, 0, pData, 0, m_nLeng);
        m_pData = pData;
        return true;
    }
    public void Clear()
    {
        m_pData = new _Ty[0];
        m_nLeng = 0;
    }
	public void FastClear()
	{
		m_nLeng = 0;
    }
    // fast clear and set null
    public void ClearAnSetNull()
    {
        if (m_nLeng <= 0)
            return;
        _Ty defVal = default(_Ty);
        for (int i = 0; i < m_nLeng; ++i)
        {
            m_pData[i] = defVal;
        }
        m_nLeng = 0;
    }
    public int size()
    {
        return m_nLeng;
    }
    public bool IsValid(int nIndex)
    {
        return nIndex >= 0 && nIndex < m_nLeng;
    }
    public void push_front(_Ty value)
    {
        if (m_nLeng >= m_pData.Length)
        {
            int nNewLen = m_pData.Length == 0 ? 8 : m_pData.Length;
            reserve(nNewLen * 2);
        }
        for (int i = m_nLeng; i > 0; --i)
        {
            m_pData[i] = m_pData[i - 1];
        }
        m_pData[0] = value;
        ++m_nLeng;
    }
    public void push_back(_Ty value)
    {
        if (m_nLeng >= m_pData.Length)
        {
            int nNewLen = m_pData.Length == 0 ? 8 : m_pData.Length;
            reserve(nNewLen * 2);
        }
        m_pData[m_nLeng++] = value;
    }
    // 功能：重载下标运算符
    public _Ty this[int nIndex]
    {
        get { return m_pData[nIndex]; }
        set { m_pData[nIndex] = value; }
    }
    public _Ty front
    {
        get
        {
            return m_pData[0];
        }
    }
    public _Ty back
    {
        get
        {
            return m_pData[m_nLeng - 1];
        }
    }
    public _Ty Get(int nIndex)
    {
        return m_pData[nIndex];
    }
    public void Set(int nIndex, _Ty value)
    {
        m_pData[nIndex] = value;
    }
    public void Remove(int nIndex)
    {
        if (IsValid(nIndex))
        {
            for (; nIndex < m_nLeng - 1; ++nIndex)
            {
                m_pData[nIndex] = m_pData[nIndex + 1];
            }
            m_pData[nIndex] = default(_Ty);
            --m_nLeng;
        }
    }
    public void pop_front()
    {
        Remove(0);
    }
    public void pop_back()
    {
        Remove(m_nLeng - 1);
    }

    public void GrowSet(int nIndex, _Ty value)
    {
        if (nIndex < 0)
            return;
        if (nIndex >= m_nLeng)
        {
            if (!reserve(nIndex + 1))
                return;
            m_nLeng = nIndex + 1;
        }
        m_pData[nIndex] = value;
    }
    public int FindNextNull(int nIndex)
    {
        for (; nIndex < m_nLeng; ++nIndex)
        {
            if (m_pData[nIndex] == null)
                return nIndex;
        }
        return m_nLeng;
    }
    public _Ty[] ToArray()
    {
        if (0 == m_nLeng)
            return null;
        _Ty[] aTemp = new _Ty[m_nLeng];
        Array.Copy(m_pData, 0, aTemp, 0, m_nLeng);
        return aTemp;
    }
    public bool Sort(Comparison<_Ty> comparer)
    {
        if (m_nLeng <= 1)
            return false;

        bool bSort = false;
        _Ty temp;
        int i = m_nLeng - 1;
        int j = 0;
        int nSwapIndex = 0;
        while (i > 0)
        {
            nSwapIndex = 0;
            for (j = 0; j < i; j++)
            {
                if (comparer(m_pData[j + 1], m_pData[j]) < 0)
                {//
                    temp = m_pData[j + 1];
                    m_pData[j + 1] = m_pData[j];
                    m_pData[j] = temp;
                    nSwapIndex = j;//记录交换下标
                    bSort = true;
                }
            }
            i = nSwapIndex;
        }
        return bSort;
    }
    public delegate int custom_compare<_TyParam>(_Ty p1, _Ty p2, _TyParam param);
    public bool Sort<_TyParam>(custom_compare<_TyParam> comparer, _TyParam param)
    {
        if (m_nLeng <= 1)
            return false;
        bool changed = true;
        bool bSort = false;

        while (changed)
        {
            changed = false;

            for (int i = 1; i < m_nLeng; ++i)
            {
                if (comparer(m_pData[i - 1], m_pData[i], param) > 0)
                {
                    _Ty temp = m_pData[i];
                    m_pData[i] = m_pData[i - 1];
                    m_pData[i - 1] = temp;
                    changed = true;
                    bSort = true;
                }
            }
        }
        return bSort;
    }
};
